﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Json;
using System.Data;
using System.IO;
using System.Reflection;

namespace Xiaov.SmartWeb.Infrastructure.ExtMethod
{
    public static class JsonExt
    {

        public static string ToJsonForGrid (this DataTable dt ,int page,int pageSize)
        {
            string JsonData = "";
            int rowbegin = (page - 1) * pageSize;
            int rowend = page * pageSize;
            if (rowend > dt.Rows.Count)
                rowend = dt.Rows.Count;
            if (rowbegin <= dt.Rows.Count)
            {
                JsonData = "{\"total\":" + dt.Rows.Count + ",\"rows\":[";
                for (int i = rowbegin; i <= rowend - 1; i++)
                {
                    JsonData += "{";
                    foreach (DataColumn dc in dt.Columns)
                    {
                        string content = Microsoft.JScript.GlobalObject.escape(dt.Rows[i][dc.ColumnName].ToString());
                        JsonData += "\"" + dc.ColumnName + "\":\"" + content + "\",";
                    }
                    JsonData = JsonData.Remove(JsonData.Length - 1);
                    JsonData += "},";
                }
                JsonData = JsonData.Remove(JsonData.Length - 1);
                JsonData += "]}";
            }
            return JsonData;
        }

        public static string ToJsonForGrid<T>(this IList<T> entitys, int page, int pageSize)
        {
            string JsonData = "";
            int rowbegin = (page - 1) * pageSize;
            int rowend = page * pageSize;
            if (rowend > entitys.Count)
                rowend = entitys.Count;
            if (rowbegin <= entitys.Count)
            {
                JsonData = "{\"total\":" + entitys.Count + ",\"rows\":[";
                for (int i = rowbegin; i <= rowend - 1; i++)
                {
                    System.Reflection.PropertyInfo[] properties = entitys[0].GetType().GetProperties();
                    JsonData += "{";
                    foreach (var q in properties)
                    {
                        JsonData += "\"" + q.Name + "\":\"" + Microsoft.JScript.GlobalObject.escape(q.GetValue(entitys[i], null)) + "\",";
                    }
                    JsonData = JsonData.Remove(JsonData.Length - 1);
                    JsonData += "},";
                }
                JsonData = JsonData.Remove(JsonData.Length - 1);
                JsonData += "]}";
            }
            return JsonData;
        }

        public static string ToJsonForGrid(this DataTable dt)
        {
            string JsonData = "[";
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                JsonData += "{";
                foreach (DataColumn dc in dt.Columns)
                {
                    string content = Microsoft.JScript.GlobalObject.escape(dt.Rows[i][dc.ColumnName].ToString());
                    JsonData += "\"" + dc.ColumnName + "\":\"" + content + "\",";
                }
                JsonData = JsonData.Remove(JsonData.Length - 1);
                JsonData += "},";
            }
            if (JsonData.Length > 1)
            {
                JsonData = JsonData.Remove(JsonData.Length - 1);
            } 
            JsonData += "]";
            return JsonData;
        }

        public static string ToJsonForGrid<T>(this IList<T> entitys)
        {
            string JsonData = "[";
            foreach(var t in entitys)
            {
                JsonData += "{";
                System.Reflection.PropertyInfo[] properties = t.GetType().GetProperties();
                foreach (var q in properties)
                {
                    JsonData += "\"" + q.Name + "\":\"" + Microsoft.JScript.GlobalObject.escape(q.GetValue(t,null)) + "\",";
                }
                JsonData = JsonData.Remove(JsonData.Length - 1);
                JsonData += "},";
            }
            if(JsonData.Length>1)
                JsonData = JsonData.Remove(JsonData.Length - 1);
            JsonData += "]";
            return JsonData;           
        }

        public static string ToJsonForComboGrid(this DataTable dt)
        {
            string JsonData = "[";
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                JsonData += "{";
                foreach (DataColumn dc in dt.Columns)
                {
                    string content = dt.Rows[i][dc.ColumnName].ToString();
                    JsonData += "\"" + dc.ColumnName + "\":\"" + content + "\",";
                }
                JsonData = JsonData.Remove(JsonData.Length - 1);
                JsonData += "},";
            }
            if(JsonData.Length>1)
                JsonData = JsonData.Remove(JsonData.Length - 1);
            JsonData += "]";
            return JsonData;
        }

        public static string ToJsonForComboGrid<T>(this IList<T> entitys)
        {
            string JsonData = "[";
            foreach (var t in entitys)
            {
                JsonData += "{";
                System.Reflection.PropertyInfo[] properties = t.GetType().GetProperties();
                foreach (var q in properties)
                {
                    JsonData += "\"" + q.Name + "\":\"" + q.GetValue(t, null).ToRequestString() +"\",";
                }
                JsonData = JsonData.Remove(JsonData.Length - 1);
                JsonData += "},";
            }
            if(JsonData.Length>1)
                JsonData = JsonData.Remove(JsonData.Length - 1);
            JsonData += "]";
            return JsonData;
        }

        public static string ToJsonForComboTree(this DataTable dt, string idField, string textField, string parentIdField, 
            string rootIdValue,string selecedId,bool hasNoNode)
        {
            string JsonData = "[";
            if (hasNoNode)
            {
                 JsonData += "{\"id\":\"0\",\"text\":\"无\"},";
            }
            DataRow[] drs = dt.Select(parentIdField + "='" + rootIdValue+"'");
            foreach (var d in drs)
            {
                DataRow[] childdrs = dt.Select(parentIdField + "='" + d[idField]+"'");
                JsonData += "{";
                JsonData += "\"id\":\"" + d[idField] + "\",";
                if (d[idField].ToString() == rootIdValue)
                    JsonData += "\"checked\":true,";
                JsonData += "\"text\":" + "\"" + d[textField] + "\"";
                if (childdrs.Count() > 0)
                {
                    JsonData += ",\"children\":";
                    JsonData += dt.ToJsonForComboTree(idField, textField, parentIdField, d[idField].ToString(),"",false);
                    JsonData += "},";
                }
                else
                {
                    JsonData += "},";
                }
            }
            if(JsonData.Length>1)
            JsonData = JsonData.Remove(JsonData.Length - 1);
            JsonData += "]";
            return JsonData;
        }       

        public static string ToJsonForTreeGrid(this DataTable dt, string idField, string parentIdField, string rootIdValue)
        {
            string JsonData = "[";
            DataRow[] drs = dt.Select(parentIdField + "='" + rootIdValue+"'");
            foreach (var d in drs)
            {
                JsonData += "{";
                foreach (DataColumn dc in dt.Columns)
                {
                    string content = Microsoft.JScript.GlobalObject.escape(d[dc.ColumnName].ToString());
                    JsonData += "\"" + dc.ColumnName + "\":\"" + content + "\",";
                }
                DataRow[] childdrs = dt.Select(parentIdField + "='" + d[idField]+"'");
                if (childdrs.Count() > 0)
                {
                    JsonData += "\"children\":";
                    JsonData += ToJsonForTreeGrid(dt, idField, parentIdField, d[idField].ToString());
                    JsonData += "},";
                }
                else
                {
                    JsonData = JsonData.Remove(JsonData.Length - 1);
                    JsonData += "},";
                }
            }
            if(JsonData.Length>1)
            JsonData = JsonData.Remove(JsonData.Length - 1);
            JsonData += "]";
            return JsonData;
        }

        public static string ToJsonForTree(this DataTable dt, string idField,string textField, string parentIdField, string rootIdValue)
        {
            string JsonData = "[";
            DataRow[] drs = dt.Select(parentIdField + "='" + rootIdValue + "'");
            foreach (var d in drs)
            {
                JsonData += "{";

                JsonData += "\"text\":\"" + d[textField].ToString() + "\",";
                JsonData += "\"id\":\"" + d[idField].ToString() + "\",";                
                DataRow[] childdrs = dt.Select(parentIdField + "='" + d[idField] + "'");
                if (childdrs.Count() > 0)
                {
                    JsonData += "\"children\":";
                    JsonData += ToJsonForTree(dt, idField, textField,parentIdField, d[idField].ToString());
                    JsonData += "},";
                }
                else
                {
                    JsonData = JsonData.Remove(JsonData.Length - 1);
                    JsonData += "},";
                }
            }
            if(JsonData.Length>1)
                JsonData = JsonData.Remove(JsonData.Length - 1);
            JsonData += "]";
            return JsonData;
        }

        public static string ToJsonForCombobox(this DataTable dt, string idField, string textField ,string selectedValue)
        {
            string JsonData = "[";
            foreach (DataRow d in dt.Rows)
            {
                JsonData += "{";

                JsonData += "\"text\":\"" + d[textField].ToString() + "\",";
                JsonData += "\"id\":\"" + d[idField].ToString() + "\",";
                if (d[idField].ToString() == selectedValue)
                    JsonData += "\"selected:\":true,";
                JsonData = JsonData.Remove(JsonData.Length - 1);
                JsonData += "},";
                
            }
            if (JsonData.Length > 1)
                JsonData = JsonData.Remove(JsonData.Length - 1);
            JsonData += "]";
            return JsonData;
        }

        public static string ToJsonForTree(this DataTable dt, string idField, string textField, string parentIdField, string rootIdValue,string urlField)
        {
            string JsonData = "[";
            DataRow[] drs = dt.Select(parentIdField + "='" + rootIdValue + "'");
            foreach (var d in drs)
            {
                JsonData += "{";

                JsonData += "\"text\":\"" + d[textField].ToString() + "\",";
                JsonData += "\"id\":\"" + d[idField].ToString() + "\",";
                JsonData += "\"attributes\":{\"url\":\""+d[urlField]+"\"},";
                DataRow[] childdrs = dt.Select(parentIdField + "='" + d[idField] + "'");
                if (childdrs.Count() > 0)
                {
                    JsonData += "\"children\":";
                    JsonData += ToJsonForTree(dt, idField, textField, parentIdField, d[idField].ToString(),urlField);
                    JsonData += "},";
                }
                else
                {
                    JsonData = JsonData.Remove(JsonData.Length - 1);
                    JsonData += "},";
                }
            }
            if (JsonData.Length > 1) 
                JsonData = JsonData.Remove(JsonData.Length - 1);
            JsonData += "]";
            return JsonData;
        }

        public static DataTable ToDataTable<T>(this IList<T> entitys)
        {
            if (entitys == null || entitys.Count <= 0)
            {
                return null;
            }
            DataTable dtReturn = new DataTable();

            // column names

            PropertyInfo[] oProps = null;

            // Could add a check to verify that there is an element 0

            foreach (T rec in entitys)
            {

                // Use reflection to get property names, to create table, Only first time, others will follow

                if (oProps == null)
                {

                    oProps = ((Type)rec.GetType()).GetProperties();

                    foreach (PropertyInfo pi in oProps)
                    {

                        Type colType = pi.PropertyType; if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>)))
                        {

                            colType = colType.GetGenericArguments()[0];

                        }

                        dtReturn.Columns.Add(new DataColumn(pi.Name, colType));

                    }

                }

                DataRow dr = dtReturn.NewRow(); foreach (PropertyInfo pi in oProps)
                {

                    dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue(rec, null);

                }

                dtReturn.Rows.Add(dr);

            }

            return (dtReturn);

        }

        public static string ToJson<T>(this T data)
        {

            try
            {

                System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(data.GetType());

                using (MemoryStream ms = new MemoryStream())
                {

                    serializer.WriteObject(ms, data);

                    return Encoding.UTF8.GetString(ms.ToArray());

                }

            }

            catch
            {

                return null;

            }

        }
    }
}
